/*
 * 文件名：BaseService.java
 * 版权：MoonBox 
 * 修改人：Peter
 * 修改时间：2018年10月15日
 * 修改内容：新增
 */
package com.renzhebiao.lkang.base;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.transaction.annotation.Transactional;

import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.renzhebiao.lkang.master.Dict;
import com.renzhebiao.lkang.page.PageDTO;
import com.renzhebiao.lkang.page.PaginationDTO;
import com.renzhebiao.lkang.request.RequestCache;
import com.renzhebiao.lkang.utils.BeanCopys;
import com.renzhebiao.lkang.utils.EmptyTools;

import lombok.extern.log4j.Log4j;

/**
 * TODO 添加类的一句话简单描述。
 * <p>
 * TODO 详细描述
 * 
 * @author Peter
 * @param <T>
 * @since 1.0.0
 */
@Log4j
public abstract class BaseService<T extends BasePO> {

    private static final int MAX_THREAD      = 5;

    private static final int TIMES_THRESHOLD = 3;

    private static final int TIMEOUT         = 20;

    private static final int RANDOM          = 10;
    /**
     * 通用mapper实例
     */
    @Autowired
    private BaseMapper<T>    mapper;

    /**
     * 没有UserID则返回admin的ID=1
     * 
     * @return UserID
     */
    public Long userId() {
        Long uid = RequestCache.userId();
        if (uid == null) {
            uid = 1L;
        }
        return uid;
    }

    /**
     * // private int maxThread = Propertiess.getInt("db.reader.list.maxThread", MAX_THREAD); private ApplicationContext
     * applicationContext; public int maxThread() { return MAX_THREAD; } /** {@inheritDoc}
     */
    private ApplicationContext applicationContext;

    public void setApplicationContext(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }

    /**
     * 转db page
     * 
     * @param pagination
     * @return
     */
    public <K, E> Page<T> getPage(PaginationDTO<K, E> pagination) {
        Page<T> pagePO = new Page<T>(pagination.getCurrent(), pagination.getSize());
        K condition = pagination.getCondition();
        // E orderByField = pagination.getOrderByField();
        // 如果客户端带Total，则不查询Total
        if (EmptyTools.notNull(pagination.getTotal())) {
            pagePO.setTotal(pagination.getTotal());
            pagePO.setSearchCount(false);
        }
        boolean asc = pagination.isAsc();
        if (condition != null) {
            pagePO.setCondition(BeanCopys.toMap(condition));
        }
        // if (orderByField != null) {
        // pagePO.setOrderByField(Strings.uncapitalize(orderByField.toString()));
        // }
        if (!asc) {
            pagePO.setAsc(asc);
        }
        return pagePO;
    }

    /**
     * 转PageDTO
     * 
     * @param pagination
     * @return
     */
    public <K> PageDTO<K> getPage(Page<T> page) {
        return new PageDTO<K>(page.getCurrent(), page.getSize(), page.getTotal(), page.getPages());
    }

    /**
     * 转PageDTO
     * 
     * @param pagination
     * @return
     */
    public <K> PageDTO<K> getPage(Page<T> page, List<K> records) {
        PageDTO<K> p = getPage(page);
        p.setRecords(records);
        return p;
    }

    public EntityWrapper<T> wrapper() {
        return new EntityWrapper<>();
    }

    public EntityWrapper<T> wrapper(T v) {
        return new EntityWrapper<>(v);
    }

    /**
     * 设置applicationContext
     * 
     * @return 返回applicationContext
     */
    public ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    /**
     * 逻辑删除
     * <p>
     * 软删除
     * 
     * @param id 业务id
     */
    @Transactional
    public void deleteByLogic(Long id, Class<T> clazz) {
        T record = null;
        try {
            record = clazz.newInstance();
        } catch (InstantiationException e) {
            log.error("Failed to deleteByLogic", e);
        } catch (IllegalAccessException e) {
            log.error("Failed to deleteByLogic", e);
        }
        record.setId(id);
        record.updated(userId());
        record.setEnabled(Dict.Whether.NO);
        mapper.updateById(record);
    }

}
